"""
登录，认证等非app的schema
"""
import traceback  # 错误堆栈信息处理
from typing import Any, Optional

from ninja_extra import service_resolver
from ninja_extra.controllers import RouteContext
from ninja_schema import Schema, ModelSchema


class Message(Schema):
    msg: str
    detail: Optional[str] = None


class BaseSchema(ModelSchema):

    def create(self, **kwargs: Any) -> Any:
        context: RouteContext = service_resolver(RouteContext)
        """重写函数创建对象的方法"""
        # 获取配置中的模型类
        model_class = self.Config.model
        """"
        model_class = self.Config.model
        如果用ninja的Schema或ModelSchema，上面Config后面的model会报未解析的特性引用
        
        原因：ninja和ninja_schema中的Schema或ModelSchema配置不同，
        ninja 用的是Class Meta:
        ninja_schema用的是 Class Config：
        """
        # 将当前对象的属性转化为字典
        data = self.dict()
        # 更新数据字典，添加传入的参数
        data.update(kwargs)

        try:
            # 调用模型类的默认管理器进行创建对象操作，传入数据字典
            instance = model_class._default_manager.create(**data)
            # 返回创建的对象实例
            return instance
        except TypeError as e:
            # 获取异常信息
            tb = traceback.format_exc()
            # 使用f-string构建错误消息，增强可读性
            msg = f"Got a `TypeError` when calling `{model_class.__name__}.{model_class._default_manager.name}.create()`. " \
                  f"This may be because you have a writable field on the serializer class that is not a valid argument to " \
                  f"`{model_class.__name__}.{model_class._default_manager.name}.create()`. " \
                  f"You may need to make the field read-only, or override the {self.__class__.__name__}.create() method to handle " \
                  f"this correctly.\nOriginal exception was:\n {tb}"
            # 抛出带有错误消息的TypeError异常
            raise TypeError(msg) from e

    def update(self, instance: Any, **kwargs: Any) -> Any:
        """
        Args:
            instance (Any): 对象实例。
            **kwargs (Any): 关键字参数。

        Returns:
            Any: 对象实例。

        Raises:
            Exception: 如果实例为空。

        Examples:
            >>> instance = SomeClass()
            >>> instance.update(name='John', age=25)
            >>> instance.save()
        """
        if not instance:
            raise Exception("需要传入实例")
        data = self.dict(exclude_none=True)
        data.update(kwargs)
        for attr, value in data.items():
            setattr(instance, attr, value)
        instance.save()
        return instance

    def save(self, instance: Optional[Any] = None, **kwargs: Any) -> Any:
        if instance:
            result = self.update(instance, **kwargs)
            assert result is not None, "`update()` did not return an object instance."
        else:
            result = self.create(**kwargs)
            assert result is not None, "`create()` did not return an object instance."

        return result
